/**
 *  gcc random_alloc_free_test_tlsf.c ../tlsf/tlsf.c -I../tlsf
 */

#include "tlsf.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#define POOL_SIZE      (1024 * 1024) // 1MB
#define OPERATIONS     100000
#define MAX_PTRS       OPERATIONS
#define MIN_ALLOC_SIZE 8
#define MAX_ALLOC_SIZE 512

void random_alloc_free_test_tlsf_c()
{
    void* pool = malloc(POOL_SIZE);
    if (! pool) {
        printf("Failed to allocate memory pool.\n");
        return;
    }

    tlsf_t tlsf = tlsf_create_with_pool(pool, POOL_SIZE);
    if (! tlsf) {
        printf("Failed to create TLSF pool.\n");
        free(pool);
        return;
    }

    void* allocated_ptrs[MAX_PTRS] = {0};
    size_t  allocated_count = 0;

    srand((unsigned int)time(NULL)); // 用当前时间作为随机种子

    clock_t start_time = clock();

    for (int i = 0;  i < OPERATIONS;  i++) {
        int op = rand() % 100;

        if (op < 70) {                                  // 70% malloc
            size_t size = MIN_ALLOC_SIZE +
                               (rand() % (MAX_ALLOC_SIZE - MIN_ALLOC_SIZE + 1));
            void* p = tlsf_malloc(tlsf, size);
            if (p && allocated_count < MAX_PTRS) {
                allocated_ptrs[allocated_count++] = p;
            }
        }
        else if (allocated_count > 0) {                 // 30% free
            size_t idx = rand() % allocated_count;
            void* p = allocated_ptrs[idx];
            tlsf_free(tlsf, p);
            // 将数组尾部的指针移到 idx 位置，快速删除
            allocated_ptrs[idx] = allocated_ptrs[allocated_count - 1];
            allocated_ptrs[allocated_count - 1] = NULL;
            allocated_count--;
        }
    }

    // 最后全部 free 掉
    for (size_t i = 0; i < allocated_count; ++i) {
        if (allocated_ptrs[i]) {
            tlsf_free(tlsf, allocated_ptrs[i]);
        }
    }

    clock_t end_time = clock();

    double elapsed_secs = (double)(end_time - start_time) / CLOCKS_PER_SEC;
    printf("Performed %d mixed malloc/free operations.\n", OPERATIONS);
    printf("Total time: %.6f seconds\n", elapsed_secs);
    printf("Average time per operation: %.2f microseconds\n", (elapsed_secs * 1e6) / OPERATIONS);

    tlsf_destroy(tlsf);
    free(pool);
}

int main()
{
    random_alloc_free_test_tlsf_c();
    return 0;
}
